package com.example.cabinetcontrol.port;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.example.cabinetcontrol.android_serialport_api.SerialPort2;
import com.example.cabinetcontrol.data.Constant;
import com.example.cabinetcontrol.data.MyData;
import com.example.cabinetcontrol.util.CommonUtils;
import com.example.cabinetcontrol.util.ILockCallBack;
import com.example.cabinetcontrol.util.L;
import com.example.cabinetcontrol.util.PreferencesUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

public class SerialPortService extends Service {
    MyData myData;
    CommonUtils commonUtils;
    Constant constant;

    private SerialPort2 mLockSerialPort;
    private OutputStream mLockOutputStream;
    private InputStream mLockInputStream;

    ILockCallBack iCabinetCallBack;
    private boolean isDoorStatus = false ; //锁板信号返回执行的线程

    boolean isCheckDoor = false;//发送查询门状态
    long startCheckDoorTime = 0;//发送时间

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        L.e("Service onBind");
        return binder;
    }

    // 创建一个内部类的实例，被活动获得后，操作服务
    public mBinder binder = new mBinder();

    // 创建一个内部类，继承自Binder，需要活动操作的函数都定义在这个内部类中
    public class mBinder extends Binder {

        public void setICabinetCallBack(ILockCallBack iCallBack){
            iCabinetCallBack = iCallBack;

            myData = new MyData(getApplicationContext());
            commonUtils = new CommonUtils(getApplicationContext());
            openLockSerialPort();//打开开锁串口

            isDoorStatus = true ;
            new Thread(new DoorStatus(mLockInputStream)).start();
            Log.d("Context","赋值");
        }

        //发送开门指令
        public void openDoor() {
            Log.d("Context","发送开门指令！");
            int time = PreferencesUtils.getInt(SerialPortService.this, constant.LOCK_OUTTIME,6);

            byte[] bs = commonUtils.commandBytes((byte) 0x01, (byte) 0xD1, (byte) 0x01, time);
            sendCommand(mLockSerialPort, mLockOutputStream, bs);
        }

        //查柜机标签数据
        public void getTemperature() {
            Log.d("Context","发送查温度数据！");
            //01 04 00 01 00 02 20 0B
            byte[] bs = new byte[]{
                    (byte) 0x01,
                    (byte) 0x04,
                    (byte) 0x00,
                    (byte) 0x01,
                    (byte) 0x00,
                    (byte) 0x02,
                    (byte) 0x20,
                    (byte) 0x0B
            };
            sendCommand(mLockSerialPort, mLockOutputStream, bs);
        }

        //查门状态
        public void getDoorStatus() {
            isCheckDoor = true;
            startCheckDoorTime = System.currentTimeMillis();
            byte[] bs = commonUtils.commandBytes((byte) 0x01, (byte) 0xD2, (byte) 0x01, 6);
            sendCommand(mLockSerialPort, mLockOutputStream, bs);
        }

        public void stop(){
            StopSerialPortService();
        }

    }


    /**
     * 打开开锁串口
     * COM1(232)----->ttymxc1 COM2(232)------->ttymxc2 COM3(232)---------->ttymxc3
     * COM4(232)--------->ttyUSB0 COM1(485)-------->ttymxc5  ttyMT1
     */
    public void openLockSerialPort() {
        try {
            mLockSerialPort = new SerialPort2(new File("/dev/ttyS3"), 9600, 0, 0);
            mLockOutputStream = mLockSerialPort.getOutputStream();
            mLockInputStream = mLockSerialPort.getInputStream();
        } catch (Exception e) {
            iCabinetCallBack.callBackMsg(0,"openLockSerialPort error:"+e);
        }
    }


    //门状态
    private class DoorStatus implements Runnable {

        private InputStream is;

        private DoorStatus(InputStream is){
            this.is = is ;
        }

        @Override
        public void run() {
            boolean isCallBack;
            while (isDoorStatus) {
                try {
                    if (is == null) {
                        return;
                    }
                    Thread.sleep(10); // 间隔100ms获取一次门状态
                    int size = 12;
                    if (is.available() >= 7) {
                        isCallBack = false;
                        Thread.sleep(10);
                        byte[] buffer = new byte[size];
                        is.read(buffer,0,1);
                        size = size-1;
                        String head1 = readStream(buffer,0,1);
                        String head2 = "";
                        if (!head1.equals("5B") && !head1.equals("01")){
                            continue;
                        }
                        else {
                            is.read(buffer,1,1);
                            size = size-1;
                            head2 = readStream(buffer,1,2);
                            if (!head2.equals("B5") && !head2.equals("04")){
                                continue;
                            }
                        }

                        if (head1.equals("5B") && head2.equals("B5")) {
                            try {
                                is.read(buffer, 2, size);
                                commonUtils.xorVerify(buffer);
                                byte[] StrBuffer = Arrays.copyOfRange(buffer, 6, 8);

                                StringBuilder Strsb = new StringBuilder();

                                String doorsb;
                                String locksb;

                                byte b;
                                for (int i = 0; i < StrBuffer.length; i++) {
                                    b = StrBuffer[i];
                                    Strsb.append(new StringBuilder(
                                            String.format("%8s", Integer.toBinaryString(Integer.valueOf(String.valueOf(commonUtils.hex(b)), 16)))
                                                    .replace(" ", "0")));
                                }
                                doorsb = Strsb.substring(0, 8);
                                locksb = Strsb.substring(8, 16);
                                //锁起 0 ，门开 1
                                if (doorsb.substring(doorsb.length() - 1, doorsb.length()).equals("1")
                                        && locksb.substring(locksb.length() - 1, locksb.length()).equals("0")) {
                                    if (constant.doorlock == 0) {
                                        constant.doorlock = 1;
                                        iCabinetCallBack.callBackDoorStatus(constant.doorlock, constant.closeType,
                                                readStream(buffer,6,8));
                                        isCallBack = true;
                                    }

                                }
                                //锁起了，门开了
                                else if (doorsb.substring(doorsb.length() - 1, doorsb.length()).equals("0")
                                        && locksb.substring(locksb.length() - 1, locksb.length()).equals("0")) {
                                    if (constant.doorlock == 1 || constant.doorlock == 0) {
                                        constant.doorlock = 2;
                                        iCabinetCallBack.callBackDoorStatus(constant.doorlock, constant.closeType,
                                                readStream(buffer,6,8));
                                        isCallBack = true;
                                    }
                                }
                                //锁落下，门关闭
                                else if (doorsb.substring(doorsb.length() - 1, doorsb.length()).equals("1")
                                        && locksb.substring(locksb.length() - 1, locksb.length()).equals("1")) {
                                    if (constant.doorlock != 0) {
                                        if (constant.doorlock == 2) {
                                            constant.closeType = 0;
                                        } else {
                                            constant.closeType = 1;
                                        }
                                        constant.doorlock = 0;
                                        iCabinetCallBack.callBackDoorStatus(constant.doorlock, constant.closeType,
                                                readStream(buffer,6,8));
                                        isCallBack = true;
                                    }
                                }
                                //主动查询
                                if (!isCallBack && isCheckDoor && (System.currentTimeMillis()-startCheckDoorTime)<500){
                                    isCheckDoor = false;
                                    iCabinetCallBack.callBackDoorStatus(constant.doorlock, constant.closeType,
                                            readStream(buffer,6,8));
                                }
                            }
                            catch (Exception e){
                                iCabinetCallBack.callBackMsg(0,"解析锁板 error:"+e);
                            }
                        }
                        else if (head1.equals("01") && head2.equals("04")){
                            try {
                                //温测
                                is.read(buffer, 2, 7);
                                String temperatureStr = readStream(buffer, 3, 5);//温度
                                String humidityStr = readStream(buffer, 5, 7);//湿度

                                iCabinetCallBack.callBackTemperature(
                                                Integer.parseInt(temperatureStr, 16) / 10,
                                                Integer.parseInt(humidityStr, 16) / 10);
                            }
                            catch (Exception e){
                                iCabinetCallBack.callBackMsg(0,"温度接收 error："+e);
                            }
                        }
                        else {
                        }
                    }
                } catch (Exception e) {
                    iCabinetCallBack.callBackMsg(0,"扫描门状态异常:"+e);
                }
            }
        }
    }

    //读取数据流
    private String readStream(byte[] headBuffer,int from ,int to){
        byte[] doorsubBuffer = Arrays.copyOfRange(headBuffer, from, to);
        StringBuilder doorsb = new StringBuilder();
        byte bt;
        for (int i=0;i<to-from;i++) {
            bt = doorsubBuffer[i];
            doorsb.append(String.valueOf(commonUtils.hex(bt)));
        }
        return doorsb.toString();
    }

    /**
     * 发送命令
     * @param sp
     * @param os
     * @param bs
     */
    private synchronized void sendCommand(SerialPort2 sp, OutputStream os, byte[] bs) {
        if (sp == null)
            return;
        if (os == null)
            return;
        try {
            os.write(bs);
            os.flush();
        } catch (IOException e) {
//            commonUtils.writeLog("串口通信异常！");
        }
    }

    //结束socket
    public void StopSerialPortService(){
        stopSelf();
    }

    @Override
    public void onDestroy() {
        try {
            Log.d("Context","SerialPortService onDestroy");

            isDoorStatus = false ;
            mLockSerialPort.close();
            mLockInputStream.close();
            mLockOutputStream.close();
        }
        catch(Exception e){
            Log.d("Context","关闭数据流出错:"+e);
        }
        super.onDestroy();
    }

}
